﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Web;
using log4net;

namespace SharePoint.Orm {
	public class WebContextStack<T> : ContextStackSkeleton<T> where T : class {
		private static readonly ILog _log = LogManager.GetLogger(typeof(WebContextStack<T>));
		private static readonly object _myLock = new object();

		protected override void DoStackOperation(Action<Stack<T>> action) {
			lock (_myLock) {
				HttpContext httpContext = HttpContext.Current;
				if (httpContext != null) {
					DoStackOperation(httpContext, action);
				} else {
					throw new Exception("Could not find HttpContext");
				}
			}
		}

		public static void DoStackOperation(HttpContext httpContext, Action<Stack<T>> action) {
			string key = GetHttpContextKey(httpContext);
			Stack<T> stack = (Stack<T>)httpContext.Items[key];
			if (stack == null) {
				stack = new Stack<T>();
				httpContext.Items[key] = stack;
			}
			if (stack.Count > 0)
				action(stack);
			if (_log.IsDebugEnabled) {
				_log.Debug("Context stack has " + stack.Count + " items.");
			}
		}

		private static string GetHttpContextKey(HttpContext httpContext) {
			string httpContextHashCode = "";
			if (httpContext != null) {
				httpContextHashCode = httpContext.GetHashCode().ToString("x", CultureInfo.InvariantCulture);
			}
			return typeof(WebContextStack<T>).FullName + httpContextHashCode + Thread.CurrentContext.ContextID;
		}
	}
}
